// Copyright (C) 2023 即时通讯网(52im.net) & Jack Jiang.
// The RainbowChat Project. All rights reserved.
// 
// 【本产品为著作权产品，合法授权后请放心使用，禁止外传！】
// 【本次授权给：<北京小羊驼科技有限公司>，授权编号：<NT231212144350>，代码指纹：<A.702363430.550>，技术对接人微信：<ID: wxid_wbyootvkdcgj22>】
// 【授权寄送：<收件：苏先生、地址：北京市大兴区北京密码西区6号楼1单元301、电话：18613885610、邮箱：bd@huiyuanxiang-inc.com>】
// 
// 【本系列产品在国家版权局的著作权登记信息如下】：
// 1）国家版权局登记名(简称)和权证号：RainbowChat    （证书号：软著登字第1220494号、登记号：2016SR041877）
// 2）国家版权局登记名(简称)和权证号：RainbowChat-Web（证书号：软著登字第3743440号、登记号：2019SR0322683）
// 3）国家版权局登记名(简称)和权证号：RainbowAV      （证书号：软著登字第2262004号、登记号：2017SR676720）
// 4）国家版权局登记名(简称)和权证号：MobileIMSDK-Web（证书号：软著登字第2262073号、登记号：2017SR676789）
// 5）国家版权局登记名(简称)和权证号：MobileIMSDK    （证书号：软著登字第1220581号、登记号：2016SR041964）
// * 著作权所有人：江顺/苏州网际时代信息科技有限公司
// 
// 【违法或违规使用投诉和举报方式】：
// 联系邮件：jack.jiang@52im.net
// 联系微信：hellojackjiang
// 联系QQ号：413980957
// 授权说明：http://www.52im.net/thread-1115-1-1.html
// 官方社区：http://www.52im.net
package com.x52im.rbchat.network.http.async;

import android.content.Context;
import android.os.AsyncTask;
import android.util.Log;

import com.eva.epc.common.util.CommonUtils;
import com.eva.framework.dto.DataFromServer;
import com.x52im.rbchat.IMClientManager;
import com.x52im.rbchat.MyApplication;
import com.x52im.rbchat.logic.chat_friend.utils.ChatDataHelper;
import com.x52im.rbchat.network.http.HttpRestHelper;
import com.x52im.rainbowchat.http.logic.dto.OfflineMsgDTO;
import com.x52im.rainbowchat.im.dto.MsgBody4Group;
import com.x52im.rainbowchat.im.dto.MsgBody4Guest;
import com.x52im.rainbowchat.im.dto.MsgBodyRoot;
import com.x52im.rbchat.cache.FriendsListProvider;
import com.x52im.rbchat.logic.chat_group.utils.GChatDataHelper;
import com.x52im.rbchat.logic.chat_guest.utils.TChatDataHelper;
import com.x52im.rbchat.logic.chat_guest.utils.TMessageHelper;
import com.x52im.rbchat.utils.ToolKits;

import java.util.ArrayList;

/**
 * 通过HTTP拉取服务端存放的离线消息（异步）.
 *
 * <p>不能使用DataLoadingAsyncTask类来处理的原因在于它里面涉及到UI，否则想在
 * 非Activity的context的情况下就会出错哦。
 * 
 * <p>
 * <b>说明：excute(..) 方法目前只接收1个或0个参数，接收1个参数时表示取指定好
 * 友的离线消息，否则表示取本人的所有未读离线消息.</b>
 * 
 * @author Jack Jiang(http://www.52im.net/space-uid-1.html)
 * @version 1.0
 */
public class QueryOfflineChatMsgAsync extends AsyncTask<String, Integer, DataFromServer> {

	private final static String TAG = QueryOfflineChatMsgAsync.class.getSimpleName();

	private Context context = null;

	public QueryOfflineChatMsgAsync(Context context) {
		this.context = context;
	}

	/**
	 * 目前只接收1个或0个参数，接收1个参数时表示取指定好
	 * 友的离线消息，否则表示取本人的所有离线消息.
	 */
	@Override
	protected DataFromServer doInBackground(String... params) {
		IMClientManager imc = MyApplication.getInstance2().getIMClientManager();

		// 取指定好友的离线消息？
		String fromUserUid = null;
		if(params != null && params.length>0)
			fromUserUid = (String)params[0];

		// ## Bug FIX: 20200815
		// ##          以下判断为容错处理，根据Bug上报统计，当此null出现时基本上就是实时音视频库因手机兼容性出现底层
		// ##          fetal级崩溃而导致，此判断用于友好提示用户并即时让用户退出APP，从而不要让Android APP处于脏现场中
		if(imc.getLocalUserInfo() == null) {
			ToolKits.fetalErrorAlert(context);
			return DataFromServer.createDefaultFailed();
		} else {
			// fromUserUid为null的话表示取本地用户收到所有离线消息(不区分好友)，否则表示取指定好友发过来的离线消息！
			return HttpRestHelper.submitGetOfflineChatMessagesToServer(imc.getLocalUserInfo().getUser_uid(), fromUserUid == null?null:fromUserUid);
		}
	}

	protected void onPostExecute(DataFromServer _dfs) {
		if(_dfs != null) {
			DataFromServer dfs = _dfs;
			// 取好友列表数据成功则把最新列表数据暂存备用
			if(dfs != null && dfs.isSuccess()) {
				IMClientManager imc = MyApplication.getInstance2().getIMClientManager();

				ArrayList<OfflineMsgDTO> srcTempChatMsg = HttpRestHelper.parseGetOfflineChatMessagesFromServer((String)dfs.getReturnValue());
				if(srcTempChatMsg != null && srcTempChatMsg.size() > 0) {
					Log.d(TAG , "离线消息读取成功，共有消息条数：" + srcTempChatMsg.size());

					// 逐条处理离线消息
					for(OfflineMsgDTO tcmd : srcTempChatMsg) {
						Log.i(TAG, "正在处理离线消息数据DTO->"+tcmd);

						// 【补充说明】：因离线消息不是全量消息（服务端只存的是该次未上线前的离线），所以服务端无法对撤回消息指令在服务端存储时就对原消息进行处
						//             理（因为可能原消息早就是在客户端了，比如本次客户端掉前），因此目前离线撤回指令就是在客户收到后再进行撤回逻辑的处理的哦

						int chatType = CommonUtils.getIntValue(tcmd.getChat_type(), -1);
						// 普通群组离线聊天消息
						if(chatType == MsgBodyRoot.CHAT_TYPE_GROUP$CHAT) {
							MsgBody4Group dd = MsgBody4Group.constructGroupChatMsgBody(tcmd.getMsg_type(), tcmd.getUser_uid(), tcmd.getNickName(), tcmd.getGroup_id(), tcmd.getMsg_content(), tcmd.getParent_fp());

                            // 将聊天消息放天聊天数据模型中
							GChatDataHelper.addChatMessageData_incoming(context
									// 参见服API文档：https://docs.52im.net/extend/docs/api/rainbowchatserver4_pro/com/x52im/rainbowchat/http/logic/dto/OfflineMsgDTO.html
									, tcmd.getMsg_content2()
									, tcmd.getGroup_id(), tcmd.getGroup_name()
									, dd
                                    , CommonUtils.getLongValue(tcmd.getHistory_time2())//cmd.getHistoryTime2ForDefaultTimeZone()
									, false, false);

						}
						// 普通一对一离线聊天消息（好友聊天或陌生人聊天）
						else {
							FriendsListProvider rp = imc.getFriendsListProvider();

							// 【正式聊天消息】该离线消息的发送者在好友列表中（是我的好友消息）
							if (rp != null && rp.isUserInRoster2(tcmd.getUser_uid())) {
								// 好友的离线聊天消息（注意：离线消息是借TempChatMsgDTO对象用一用的，此对象里的msg_content）
								ChatDataHelper.addChatMessageData_incoming(context
										// 参见服API文档：https://docs.52im.net/extend/docs/api/rainbowchatserver4_pro/com/x52im/rainbowchat/http/logic/dto/OfflineMsgDTO.html
										, tcmd.getMsg_content2()
										, rp.getFriendInfoByUid2(tcmd.getUser_uid())
										, tcmd.getMsg_content() // 注意：msg_content存放的不是TextMessage的json文本
										, CommonUtils.getLongValue(tcmd.getHistory_time2())//tcmd.getHistoryTime2ForDefaultTimeZone()
										, false, false
										, tcmd.getMsg_type()
								);
							}
							// 【临时聊天消息】只在该人不在好友列表中，即判定该消息是临时聊天消息（即陌生人消息）
							else {
								// 将数据放入
								MsgBody4Guest dd = TMessageHelper.constructTempChatMsgDTO(
								        tcmd.getMsg_type()
										, tcmd.getUser_uid(), tcmd.getNickName()
										, tcmd.getFriend_user_uid(), tcmd.getMsg_content());

								TChatDataHelper.addChatMessageData_incoming(context
										// 参见服API文档：https://docs.52im.net/extend/docs/api/rainbowchatserver4_pro/com/x52im/rainbowchat/http/logic/dto/OfflineMsgDTO.html
										, tcmd.getMsg_content2()
										, dd
                                        , CommonUtils.getLongValue(tcmd.getHistory_time2())//tcmd.getHistoryTime2ForDefaultTimeZone()
                                        , false, false);
							}
						}
					}
				}
			} else {
				Log.e(TAG, "离线消息从服务端获取失败.");
			}
		}
	}
}